import os
import subprocess
import time
import argparse
import signal
import sys
from colorama import init, Fore

from core.BuildAndRun import clone_and_build
from core.ReadExcel import read_libraries_from_excel, get_repo_info
from utils.config import check_dependencies

# 全局变量，用于控制测试中断
interrupted = False
current_process = None  # 添加全局变量存储当前子进程
os.environ['PYTHONIOENCODING'] = 'utf-8'

# 信号处理函数
def signal_handler(sig):
    global interrupted, current_process
    print(f"\n{Fore.YELLOW}收到中断信号，正在安全停止测试...{Fore.RESET}")
    interrupted = True
    
    # 强制终止当前正在运行的子进程（如果有）
    if current_process is not None and hasattr(current_process, 'pid'):
        try:
            result = subprocess.run(
                ["taskkill", "/F", "/T", "/PID", str(current_process.pid)],
                stdout=subprocess.PIPE,
                stderr=subprocess.PIPE,
                encoding='utf-8',
                errors='ignore'
            )
            print(result.stdout)
        except Exception as e:
            print(f"终止子进程失败: {str(e)}")
    else:
        print(f"{Fore.YELLOW}当前子进程以非常规方式终止{Fore.RESET}")

    # 如果是SIGINT（Ctrl+C），则直接退出程序
    if sig == signal.SIGINT:
        print(f"{Fore.YELLOW}用户按下Ctrl+C，正在退出程序...{Fore.RESET}")
        sys.exit(1)

# 注册信号处理函数
signal.signal(signal.SIGINT, signal_handler)
signal.signal(signal.SIGTERM, signal_handler)

def run_all_libraries(repo_type, args, libraries=None, urls=None):
    global current_process, interrupted
    init()  # 初始化颜色输出
    """按顺序执行Excel中的所有库"""
    # 检查依赖
    check_dependencies()
    
    # 重置中断标志
    interrupted = False
    
    # 如果没有传入libraries和urls，则从Excel读取
    if libraries is None or urls is None:
        libraries, _, urls = read_libraries_from_excel()
    
    # 如果指定了特定库，则只测试这些库
    if hasattr(args, 'specific_libraries') and args.specific_libraries:
        specific_libraries = args.specific_libraries
        # 确保所有指定的库都在Excel中
        filtered_libraries = []
        for lib in specific_libraries:
            if lib in libraries:
                filtered_libraries.append(lib)
            else:
                print(f"警告：指定的库 {lib} 不在Excel中，将被跳过")
        libraries = filtered_libraries
        print(f"将测试 {len(libraries)} 个指定的库")

    # 如果repo_type是auto，则根据URL自动检测每个库的仓库类型
    if repo_type == "auto":
        print("使用自动检测模式确定库的仓库类型")
        filtered_libraries = []
        for lib in libraries:
            owner, name, _ = get_repo_info(lib)
            # 提取库名用于打印
            display_name = lib['name'] if isinstance(lib, dict) and 'name' in lib else lib
            if owner == "openharmony-sig":
                print(f"库 {display_name} 属于 openharmony-sig 仓库组")
                filtered_libraries.append(lib)
            elif owner == "openharmony-tpc" and name != "openharmony_tpc_samples":
                print(f"库 {display_name} 属于 openharmony-tpc 仓库组")
                filtered_libraries.append(lib)
            elif name == "openharmony_tpc_samples":
                print(f"库 {display_name} 属于 openharmony_tpc_samples 仓库组")
                filtered_libraries.append(lib)
            else:
                print(f"警告：无法确定库 {display_name} 的仓库类型，将被跳过")
        libraries = filtered_libraries
    
    # 按顺序执行每个库
    for idx, library_name in enumerate(libraries, 1):
        # 检查是否被中断
        if interrupted:
            print(f"\n{Fore.YELLOW}测试被用户中断，停止执行剩余库{Fore.RESET}")
            break

        try:
            # 提取库名用于打印
            display_name = library_name['name'] if isinstance(library_name, dict) and 'name' in library_name else library_name
            print(f"\n{'='*50}")
            print(f"开始执行第 {idx}/{len(libraries)} 个库: {display_name}")
            print(f"{'='*50}")
            
            # 解析URL获取owner、name和sub_dir
            owner, name, sub_dir = get_repo_info(library_name) # 使用原始 library_name 获取信息
            print(f"解析得到仓库信息: owner={owner}, name={name}, sub_dir={sub_dir}")

            # 调用clone and build函数并获取测试结果
            print(f"开始克隆和构建库: {display_name}")
            try:
                # 修改为使用全局变量跟踪子进程
                global current_process
                current_process = None  # 重置当前进程
                clone_and_build(library_name)
                current_process = None  # 子进程完成后重置
            except Exception as e:
                current_process = None  # 确保在异常情况下也重置
                print(f"克隆和构建时出错: {str(e)}")
                raise
                
        except (subprocess.CalledProcessError, OSError, IOError) as e:
            print(f"执行库 {library_name} 时出错: {str(e)}")
            print(f"详细错误信息:")
            print(f"- 当前工作目录: {os.getcwd()}")
            print(f"- 尝试访问的路径: {os.path.abspath(library_name['name'])}")
            if hasattr(e, 'cmd'):
                print(f"- 执行的命令: {e.cmd}")
            if hasattr(e, 'output'):
                print(f"- 命令输出: {e.output.decode('utf-8') if isinstance(e.output, bytes) else e.output}")
    print(f"{'='*50}")

if __name__ == "__main__":
    start_time = time.time()
    current_time = time.strftime("%Y/%m/%d %H时%M分%S秒", time.localtime(start_time))
    print(f"测试开始时间: {current_time}")
    
    # 获取用户输入的SDK版本
    from utils.config import SDK_API_MAPPING, set_sdk_version
    while True:
        sdk_version = input("请输入SDK版本 (例如: 5.0.4): ").strip()
        if sdk_version in SDK_API_MAPPING:
            # 使用新的函数设置版本
            set_sdk_version(sdk_version)
            break
        print(f"无效的SDK版本。支持的版本: {', '.join(SDK_API_MAPPING.keys())}")
    
    # 获取用户输入的关键词
    keyword = input("请输入要搜索的三方库关键词: ").strip().lower()
    
    # 从Excel读取所有库
    libraries, _, _ = read_libraries_from_excel()
    
    # 模糊匹配库名
    matched_libraries = []
    for lib in libraries:
        lib_name = lib['name'] if isinstance(lib, dict) and 'name' in lib else lib
        if isinstance(lib_name, str) and keyword in lib_name.lower():
            matched_libraries.append(lib)
    
    if not matched_libraries:
        print(f"未找到包含关键词 '{keyword}' 的三方库")
        sys.exit(0)
    
    print(f"找到 {len(matched_libraries)} 个匹配的三方库:")
    for idx, lib in enumerate(matched_libraries, 1):
        lib_name = lib['name'] if isinstance(lib, dict) and 'name' in lib else lib
        print(f"{idx}. {lib_name}")
    
    # 让用户选择要测试的库
    while True:
        choice = input("请输入要测试的库的序号（多个序号用空格分隔，输入 'all' 测试所有匹配的库）: ").strip()
        if choice.lower() == 'all':
            selected_libraries = matched_libraries
            break
        try:
            indices = [int(x) - 1 for x in choice.split()]
            if all(0 <= i < len(matched_libraries) for i in indices):
                selected_libraries = [matched_libraries[i] for i in indices]
                break
            else:
                print("输入的序号超出范围，请重新输入")
        except ValueError:
            print("输入格式错误，请输入有效的序号")
    
    # 创建参数对象并运行测试
    args = argparse.Namespace(output_dir=os.getcwd(), specific_libraries=selected_libraries)
    run_all_libraries(repo_type="default", args=args, libraries=selected_libraries)
    
    # Get end time and print
    end_time = time.time()
    current_time = time.strftime("%Y/%m/%d %H时%M分%S秒", time.localtime(end_time))
    print(f"测试结束时间: {current_time}")
    
    # Calculate and print duration
    duration = end_time - start_time
    hours = int(duration // 3600)
    minutes = int((duration % 3600) // 60)
    seconds = int(duration % 60)
    print(f"总耗时: {hours}小时{minutes}分钟{seconds}秒")